namespace iScadaFBD
{
    using System;
    using System.Collections;
    using System.ComponentModel;
    using System.Drawing;
    using System.Drawing.Drawing2D;
    using System.Windows.Forms;

    public class DrawArea : UserControl
    {
        private GlobalParam.FBType activedFBType;
        private int clipHeight = 500;
        private int clipWidth = 500;
        private IContainer components = null;
        private Point connectEndPoint;
        private Point connectStartPoint;
        private bool drawLine = false;
        private bool drawNetRectangle = false;
        private Size gridSize = new Size(10, 10);
        private float m_Scalef = 1f;
        private Rectangle netRectangle;
        private iScadaFBD.ObjList objList;
        private iScadaFBD.GlobalParam.RunMode runMode;
        private bool showGrid;
        private GlobalParam.IO_Type startNodeType;
        private ArrayList tempList;
        private iScadaFBD.Tool[] tools;

        public DrawArea()
        {
            this.InitializeComponent();
            this.Initial();
        }

        public string CreateObjName()
        {
            int num = 1;
            for (int i = 0; i <= (this.ObjList.Count() - 1); i++)
            {
                if (this.ObjList[i].ObjName == (this.ActivedFBType.ToString() + num.ToString()))
                {
                    num++;
                }
            }
            return (this.ActivedFBType.ToString() + num.ToString());
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing && (this.components != null))
            {
                this.components.Dispose();
            }
            base.Dispose(disposing);
        }

        private void DrawArea_DoubleClick(object sender, EventArgs e)
        {
        }

        private void DrawArea_DragDrop(object sender, DragEventArgs e)
        {
            if (this.RunMode == iScadaFBD.GlobalParam.RunMode.EDIT)
            {
                Point p = new Point(e.X, e.Y);
                p = this.ScalePoint(new Point(e.X, e.Y))[0];
                p = base.PointToClient(p);
                switch (this.activedFBType)
                {
                    case GlobalParam.FBType.AND:
                    {
                        AND_FB o = new AND_FB(p, this);
                        this.objList.UnselectAll();
                        this.objList.AddObject(o);
                        GlobalParam.order++;
                        o.ExecuteOrder = GlobalParam.order;
                        o.Selected = true;
                        break;
                    }
                    case GlobalParam.FBType.NOT:
                    {
                        NOT_FB not_fb = new NOT_FB(p, this);
                        this.objList.UnselectAll();
                        this.objList.AddObject(not_fb);
                        GlobalParam.order++;
                        not_fb.ExecuteOrder = GlobalParam.order;
                        not_fb.Selected = true;
                        break;
                    }
                    case GlobalParam.FBType.CMP:
                    {
                        CMP_FB cmp_fb = new CMP_FB(p, this);
                        this.objList.UnselectAll();
                        this.objList.AddObject(cmp_fb);
                        GlobalParam.order++;
                        cmp_fb.ExecuteOrder = GlobalParam.order;
                        cmp_fb.Selected = true;
                        break;
                    }
                    case GlobalParam.FBType.OR:
                    {
                        OR_FB or_fb = new OR_FB(p, this);
                        this.objList.UnselectAll();
                        this.objList.AddObject(or_fb);
                        GlobalParam.order++;
                        or_fb.ExecuteOrder = GlobalParam.order;
                        or_fb.Selected = true;
                        break;
                    }
                    case GlobalParam.FBType.SR:
                    {
                        COS_FB cos_fb = new COS_FB(p, this);
                        this.objList.UnselectAll();
                        this.objList.AddObject(cos_fb);
                        GlobalParam.order++;
                        cos_fb.ExecuteOrder = GlobalParam.order;
                        cos_fb.Selected = true;
                        break;
                    }
                    case GlobalParam.FBType.TON:
                    {
                        TON_FB ton_fb = new TON_FB(p, this);
                        this.objList.UnselectAll();
                        this.objList.AddObject(ton_fb);
                        GlobalParam.order++;
                        ton_fb.ExecuteOrder = GlobalParam.order;
                        ton_fb.Selected = true;
                        break;
                    }
                    case GlobalParam.FBType.TOF:
                    {
                        TOF_FB tof_fb = new TOF_FB(p, this);
                        this.objList.UnselectAll();
                        this.objList.AddObject(tof_fb);
                        GlobalParam.order++;
                        tof_fb.ExecuteOrder = GlobalParam.order;
                        tof_fb.Selected = true;
                        break;
                    }
                    case GlobalParam.FBType.AI:
                    {
                        AI_FB ai_fb = new AI_FB(p, this);
                        this.objList.UnselectAll();
                        this.objList.AddObject(ai_fb);
                        GlobalParam.order++;
                        ai_fb.ExecuteOrder = GlobalParam.order;
                        ai_fb.Selected = true;
                        break;
                    }
                    case GlobalParam.FBType.AO:
                    {
                        AO_FB ao_fb = new AO_FB(p, this);
                        this.objList.UnselectAll();
                        this.objList.AddObject(ao_fb);
                        GlobalParam.order++;
                        ao_fb.ExecuteOrder = GlobalParam.order;
                        ao_fb.Selected = true;
                        break;
                    }
                    case GlobalParam.FBType.DI:
                    {
                        DI_FB di_fb = new DI_FB(p, this);
                        this.objList.UnselectAll();
                        this.objList.AddObject(di_fb);
                        GlobalParam.order++;
                        di_fb.ExecuteOrder = GlobalParam.order;
                        di_fb.Selected = true;
                        break;
                    }
                    case GlobalParam.FBType.DO:
                    {
                        DO_FB do_fb = new DO_FB(p, this);
                        this.objList.UnselectAll();
                        this.objList.AddObject(do_fb);
                        GlobalParam.order++;
                        do_fb.ExecuteOrder = GlobalParam.order;
                        do_fb.Selected = true;
                        break;
                    }
                    case GlobalParam.FBType.DI_IN:
                    {
                        DINPARAM_FB dinparam_fb = new DINPARAM_FB(p, this);
                        this.objList.UnselectAll();
                        this.objList.AddObject(dinparam_fb);
                        GlobalParam.order++;
                        dinparam_fb.ExecuteOrder = GlobalParam.order;
                        dinparam_fb.Selected = true;
                        break;
                    }
                    case GlobalParam.FBType.DO_OUT:
                    {
                        DOUTPARAM_FB doutparam_fb = new DOUTPARAM_FB(p, this);
                        this.objList.UnselectAll();
                        this.objList.AddObject(doutparam_fb);
                        GlobalParam.order++;
                        doutparam_fb.ExecuteOrder = GlobalParam.order;
                        doutparam_fb.Selected = true;
                        break;
                    }
                    case GlobalParam.FBType.AI_IN:
                    {
                        AINPARAM_FB ainparam_fb = new AINPARAM_FB(p, this);
                        this.objList.UnselectAll();
                        this.objList.AddObject(ainparam_fb);
                        GlobalParam.order++;
                        ainparam_fb.ExecuteOrder = GlobalParam.order;
                        ainparam_fb.Selected = true;
                        break;
                    }
                    case GlobalParam.FBType.AO_OUT:
                    {
                        AOUTPARAM_FB aoutparam_fb = new AOUTPARAM_FB(p, this);
                        this.objList.UnselectAll();
                        this.objList.AddObject(aoutparam_fb);
                        GlobalParam.order++;
                        aoutparam_fb.ExecuteOrder = GlobalParam.order;
                        aoutparam_fb.Selected = true;
                        break;
                    }
                    case GlobalParam.FBType.PI:
                    {
                        PI_FB pi_fb = new PI_FB(p, this);
                        this.objList.UnselectAll();
                        this.objList.AddObject(pi_fb);
                        GlobalParam.order++;
                        pi_fb.ExecuteOrder = GlobalParam.order;
                        pi_fb.Selected = true;
                        break;
                    }
                    case GlobalParam.FBType.PID:
                    {
                        PID_FB pid_fb = new PID_FB(p, this);
                        this.objList.UnselectAll();
                        this.objList.AddObject(pid_fb);
                        GlobalParam.order++;
                        pid_fb.ExecuteOrder = GlobalParam.order;
                        pid_fb.Selected = true;
                        break;
                    }
                    case GlobalParam.FBType.ADD:
                    {
                        ADD_FB add_fb = new ADD_FB(p, this);
                        this.objList.UnselectAll();
                        this.objList.AddObject(add_fb);
                        GlobalParam.order++;
                        add_fb.ExecuteOrder = GlobalParam.order;
                        add_fb.Selected = true;
                        break;
                    }
                    case GlobalParam.FBType.SUB:
                    {
                        SUB_FB sub_fb = new SUB_FB(p, this);
                        this.objList.UnselectAll();
                        this.objList.AddObject(sub_fb);
                        GlobalParam.order++;
                        sub_fb.ExecuteOrder = GlobalParam.order;
                        sub_fb.Selected = true;
                        break;
                    }
                    case GlobalParam.FBType.MUL:
                    {
                        MUL_FB mul_fb = new MUL_FB(p, this);
                        this.objList.UnselectAll();
                        this.objList.AddObject(mul_fb);
                        GlobalParam.order++;
                        mul_fb.ExecuteOrder = GlobalParam.order;
                        mul_fb.Selected = true;
                        break;
                    }
                    case GlobalParam.FBType.DIV:
                    {
                        DIV_FB div_fb = new DIV_FB(p, this);
                        this.objList.UnselectAll();
                        this.objList.AddObject(div_fb);
                        GlobalParam.order++;
                        div_fb.ExecuteOrder = GlobalParam.order;
                        div_fb.Selected = true;
                        break;
                    }
                    case GlobalParam.FBType.ABS:
                    {
                        ABS_FB abs_fb = new ABS_FB(p, this);
                        this.objList.UnselectAll();
                        this.objList.AddObject(abs_fb);
                        GlobalParam.order++;
                        abs_fb.ExecuteOrder = GlobalParam.order;
                        abs_fb.Selected = true;
                        break;
                    }
                    case GlobalParam.FBType.SQR:
                    {
                        SQR_FB sqr_fb = new SQR_FB(p, this);
                        this.objList.UnselectAll();
                        this.objList.AddObject(sqr_fb);
                        GlobalParam.order++;
                        sqr_fb.ExecuteOrder = GlobalParam.order;
                        sqr_fb.Selected = true;
                        break;
                    }
                    case GlobalParam.FBType.SIN:
                    {
                        SIN_FB sin_fb = new SIN_FB(p, this);
                        this.objList.UnselectAll();
                        this.objList.AddObject(sin_fb);
                        GlobalParam.order++;
                        sin_fb.ExecuteOrder = GlobalParam.order;
                        sin_fb.Selected = true;
                        break;
                    }
                    case GlobalParam.FBType.COS:
                    {
                        COS_FB cos_fb2 = new COS_FB(p, this);
                        this.objList.UnselectAll();
                        this.objList.AddObject(cos_fb2);
                        GlobalParam.order++;
                        cos_fb2.ExecuteOrder = GlobalParam.order;
                        cos_fb2.Selected = true;
                        break;
                    }
                    case GlobalParam.FBType.POW:
                    {
                        EXP_FB exp_fb = new EXP_FB(p, this);
                        this.objList.UnselectAll();
                        this.objList.AddObject(exp_fb);
                        GlobalParam.order++;
                        exp_fb.ExecuteOrder = GlobalParam.order;
                        exp_fb.Selected = true;
                        break;
                    }
                    case GlobalParam.FBType.LOG:
                    {
                        LOG_FB log_fb = new LOG_FB(p, this);
                        this.objList.UnselectAll();
                        this.objList.AddObject(log_fb);
                        GlobalParam.order++;
                        log_fb.ExecuteOrder = GlobalParam.order;
                        log_fb.Selected = true;
                        break;
                    }
                    case GlobalParam.FBType.COUNTER:
                    {
                        COUNTER_FB counter_fb = new COUNTER_FB(p, this);
                        this.objList.UnselectAll();
                        this.objList.AddObject(counter_fb);
                        GlobalParam.order++;
                        counter_fb.ExecuteOrder = GlobalParam.order;
                        counter_fb.Selected = true;
                        break;
                    }
                    case GlobalParam.FBType.TIMER:
                    {
                        TIMER_FB timer_fb = new TIMER_FB(p, this);
                        this.objList.UnselectAll();
                        this.objList.AddObject(timer_fb);
                        GlobalParam.order++;
                        timer_fb.ExecuteOrder = GlobalParam.order;
                        timer_fb.Selected = true;
                        break;
                    }
                }
                this.activedFBType = GlobalParam.FBType.POINTER;
                this.Refresh();
            }
        }

        private void DrawArea_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.Text))
            {
                e.Effect = DragDropEffects.Copy;
            }
            else
            {
                e.Effect = DragDropEffects.None;
            }
        }

        private void DrawArea_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Control && (e.KeyCode == Keys.A))
            {
                this.objList.SelectAll();
                this.Refresh();
            }
            if (this.runMode != iScadaFBD.GlobalParam.RunMode.EDIT)
            {
                return;
            }
            if (e.Control && (e.KeyCode == Keys.C))
            {
                this.Refresh();
            }
            if (e.Control && (e.KeyCode == Keys.V))
            {
                this.Refresh();
            }
            if (e.KeyCode == Keys.Delete)
            {
                this.ObjList.DeleteSelection();
                this.Refresh();
            }
            switch (e.KeyCode)
            {
                case Keys.A:
                    this.MoveLeft();
                    break;

                case Keys.D:
                    this.MoveRight();
                    break;
                case Keys.S:
                    this.MoveDown();
                    break;
                case Keys.W:
                    this.MoveUp();
                    break;
            }
            this.Refresh();
        }

        private void DrawArea_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                this.tools[this.ToolType(e)].OnMouseDown(this, e);
            }
        }

        private void DrawArea_MouseMove(object sender, MouseEventArgs e)
        {
            if ((e.Button == MouseButtons.Left) || (e.Button == MouseButtons.None))
            {
                this.tools[this.ToolType(e)].OnMouseMove(this, e);
            }
            else
            {
                this.Cursor = Cursors.Default;
            }
        }

        private void DrawArea_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                this.tools[this.ToolType(e)].OnMouseUp(this, e);
            }
        }

        private void DrawArea_Paint(object sender, PaintEventArgs e)
        {
            e.Graphics.PageUnit = GraphicsUnit.Pixel;
            e.Graphics.PageScale = this.M_Scalef;
            SolidBrush brush = new SolidBrush(Color.White);
            e.Graphics.FillRectangle(brush, base.ClientRectangle);
            if (this.ShowGrid)
            {
                ControlPaint.DrawGrid(e.Graphics, base.ClientRectangle, this.gridSize, this.BackColor);
            }
            if (this.objList != null)
            {
                this.ObjList.Draw(e.Graphics, this);
            }
            this.DrawNetSelection(e.Graphics);
            this.DrawNetLine(e.Graphics);
            brush.Dispose();
        }

        public void DrawNetLine(Graphics g)
        {
            if (this.DrawLine)
            {
                int num;
                int num2;
                Pen pen = new Pen(Color.Black, 1f);
                if (this.StartNodeType == GlobalParam.IO_Type.OUTPUT)
                {
                    if (this.connectStartPoint.X < this.connectEndPoint.X)
                    {
                        num = (this.connectStartPoint.X + this.connectEndPoint.X) / 2;
                        g.DrawLine(pen, this.connectStartPoint, new Point(num, this.connectStartPoint.Y));
                        g.DrawLine(pen, new Point(num, this.connectStartPoint.Y), new Point(num, this.connectEndPoint.Y));
                        g.DrawLine(pen, new Point(num, this.connectEndPoint.Y), new Point(this.connectEndPoint.X, this.connectEndPoint.Y));
                    }
                    else
                    {
                        num2 = (this.connectStartPoint.Y + this.connectEndPoint.Y) / 2;
                        g.DrawLine(pen, this.connectStartPoint, new Point(this.connectStartPoint.X + 15, this.connectStartPoint.Y));
                        g.DrawLine(pen, new Point(this.connectStartPoint.X + 15, this.connectStartPoint.Y), new Point(this.connectStartPoint.X + 15, num2));
                        g.DrawLine(pen, new Point(this.connectStartPoint.X + 15, num2), new Point(this.connectEndPoint.X - 15, num2));
                        g.DrawLine(pen, new Point(this.connectEndPoint.X - 15, num2), new Point(this.connectEndPoint.X - 15, this.connectEndPoint.Y));
                        g.DrawLine(pen, new Point(this.connectEndPoint.X - 15, this.connectEndPoint.Y), this.connectEndPoint);
                    }
                }
                else if (this.connectStartPoint.X > this.connectEndPoint.X)
                {
                    num = (this.connectStartPoint.X + this.connectEndPoint.X) / 2;
                    g.DrawLine(pen, this.connectStartPoint, new Point(num, this.connectStartPoint.Y));
                    g.DrawLine(pen, new Point(num, this.connectStartPoint.Y), new Point(num, this.connectEndPoint.Y));
                    g.DrawLine(pen, new Point(num, this.connectEndPoint.Y), new Point(this.connectEndPoint.X, this.connectEndPoint.Y));
                }
                else
                {
                    num2 = (this.connectStartPoint.Y + this.connectEndPoint.Y) / 2;
                    g.DrawLine(pen, this.connectStartPoint, new Point(this.connectStartPoint.X - 15, this.connectStartPoint.Y));
                    g.DrawLine(pen, new Point(this.connectStartPoint.X - 15, this.connectStartPoint.Y), new Point(this.connectStartPoint.X - 15, num2));
                    g.DrawLine(pen, new Point(this.connectStartPoint.X - 15, num2), new Point(this.connectEndPoint.X + 15, num2));
                    g.DrawLine(pen, new Point(this.connectEndPoint.X + 15, num2), new Point(this.connectEndPoint.X + 15, this.connectEndPoint.Y));
                    g.DrawLine(pen, new Point(this.connectEndPoint.X + 15, this.connectEndPoint.Y), this.connectEndPoint);
                }
                pen.Dispose();
            }
        }

        public void DrawNetSelection(Graphics g)
        {
            if (this.DrawNetRectangle)
            {
                ControlPaint.DrawFocusRectangle(g, this.NetRectangle, Color.Black, Color.Transparent);
            }
        }

        protected void Initial()
        {
            this.ObjList = new iScadaFBD.ObjList();
            this.tempList = new ArrayList();
            base.SetStyle(ControlStyles.DoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.UserMouse | ControlStyles.Selectable | ControlStyles.UserPaint | ControlStyles.ContainerControl, true);
            this.tools = new iScadaFBD.Tool[2];
            this.ActivedFBType = GlobalParam.FBType.POINTER;
            this.tools[0] = new ToolPointer();
            this.tools[1] = new ToolShape(this);
            this.runMode = iScadaFBD.GlobalParam.RunMode.EDIT;
        }

        private void InitializeComponent()
        {
            this.SuspendLayout();
            // 
            // DrawArea
            // 
            this.AllowDrop = true;
            this.AutoScroll = true;
            this.AutoScrollMinSize = new System.Drawing.Size(1024, 1024);
            this.BackColor = System.Drawing.Color.White;
            this.Name = "DrawArea";
            this.Size = new System.Drawing.Size(1024, 1025);
            this.DoubleClick += new System.EventHandler(this.DrawArea_DoubleClick);
            this.Paint += new System.Windows.Forms.PaintEventHandler(this.DrawArea_Paint);
            this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.DrawArea_MouseMove);
            this.DragDrop += new System.Windows.Forms.DragEventHandler(this.DrawArea_DragDrop);
            this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.DrawArea_MouseDown);
            this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.DrawArea_MouseUp);
            this.DragEnter += new System.Windows.Forms.DragEventHandler(this.DrawArea_DragEnter);
            this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.DrawArea_KeyDown);
            this.ResumeLayout(false);

        }

        public void MoveDown()
        {
            int deltaX = 0;
            int deltaY = 1;
            for (int i = this.ObjList.SelectionCount - 1; i >= 0; i--)
            {
                this.ObjList.GetSelectedObject(i).Move(deltaX, deltaY);
            }
            this.Refresh();
        }

        public void MoveLeft()
        {
            int deltaX = -1;
            int deltaY = 0;
            for (int i = this.ObjList.SelectionCount - 1; i >= 0; i--)
            {
                this.ObjList.GetSelectedObject(i).Move(deltaX, deltaY);
            }
            this.Refresh();
        }

        public void MoveRight()
        {
            int deltaX = 1;
            int deltaY = 0;
            for (int i = this.ObjList.SelectionCount - 1; i >= 0; i--)
            {
                this.ObjList.GetSelectedObject(i).Move(deltaX, deltaY);
            }
            this.Refresh();
        }

        public void MoveUp()
        {
            int deltaX = 0;
            int deltaY = -1;
            for (int i = this.ObjList.SelectionCount - 1; i >= 0; i--)
            {
                this.ObjList.GetSelectedObject(i).Move(deltaX, deltaY);
            }
            this.Refresh();
        }

        public Point[] ScalePoint(Point MousePoint)
        {
            Graphics graphics = base.CreateGraphics();
            graphics.TranslateTransform(((float) base.AutoScrollPosition.X) / this.M_Scalef, ((float) base.AutoScrollPosition.Y) / this.M_Scalef);
            graphics.PageUnit = GraphicsUnit.Pixel;
            graphics.PageScale = this.M_Scalef;
            Size size = new Size(base.AutoScrollPosition);
            Point[] pts = new Point[] { new Point(MousePoint.X - size.Width, MousePoint.Y - size.Height) };
            graphics.TransformPoints(CoordinateSpace.Page, CoordinateSpace.Device, pts);
            return pts;
        }

        private int ToolType(MouseEventArgs e)
        {
            if ((this.activedFBType == GlobalParam.FBType.SHAPE_RECTANGLE) || (this.activedFBType == GlobalParam.FBType.SHAPE_LINE))
            {
                return 1;
            }
            return 0;
        }

        public GlobalParam.FBType ActivedFBType
        {
            get
            {
                return this.activedFBType;
            }
            set
            {
                this.activedFBType = value;
            }
        }

        public int ClipHeight
        {
            get
            {
                return this.clipHeight;
            }
            set
            {
                this.clipHeight = value;
            }
        }

        public int ClipWidth
        {
            get
            {
                return this.clipWidth;
            }
            set
            {
                this.clipWidth = value;
            }
        }

        public Point ConnectEndPoint
        {
            get
            {
                return this.connectEndPoint;
            }
            set
            {
                this.connectEndPoint = value;
            }
        }

        public Point ConnectStartPoint
        {
            get
            {
                return this.connectStartPoint;
            }
            set
            {
                this.connectStartPoint = value;
            }
        }

        public bool DrawLine
        {
            get
            {
                return this.drawLine;
            }
            set
            {
                this.drawLine = value;
            }
        }

        public bool DrawNetRectangle
        {
            get
            {
                return this.drawNetRectangle;
            }
            set
            {
                this.drawNetRectangle = value;
            }
        }

        public Size GridSize
        {
            get
            {
                return this.gridSize;
            }
            set
            {
                this.gridSize = value;
            }
        }

        public float M_Scalef
        {
            get
            {
                return this.m_Scalef;
            }
            set
            {
                this.m_Scalef = value;
            }
        }

        public Rectangle NetRectangle
        {
            get
            {
                return this.netRectangle;
            }
            set
            {
                this.netRectangle = value;
            }
        }

        public iScadaFBD.ObjList ObjList
        {
            get
            {
                return this.objList;
            }
            set
            {
                this.objList = value;
            }
        }

        public ArrayList OrderList
        {
            get
            {
                return this.tempList;
            }
            set
            {
                this.tempList = value;
            }
        }

        public iScadaFBD.GlobalParam.RunMode RunMode
        {
            get
            {
                return this.runMode;
            }
            set
            {
                this.runMode = value;
            }
        }

        public bool ShowGrid
        {
            get
            {
                return this.showGrid;
            }
            set
            {
                this.showGrid = value;
            }
        }

        public GlobalParam.IO_Type StartNodeType
        {
            get
            {
                return this.startNodeType;
            }
            set
            {
                this.startNodeType = value;
            }
        }
    }
}

